#pragma once
#include <vector>
#include <set>
#include "AniObject.h"

namespace bs
{
	class IAniSystemListener
	{
	public:
		virtual void OnAniBegin() = 0;
		virtual void OnAniEnd() = 0;
	};

	class AniSystem
	{
	public:
		AniSystem();
		~AniSystem();

		void AttachListener(IAniSystemListener* listener) { this->listeners.insert(listener); }
		void DetachListener(IAniSystemListener* listener) { this->listeners.erase(listener); }

		void Update(size_t elapse, float speedFactor);
		void Render(HDC dc);

		int AddAniElement(AniObject* ani, int preId = -1, bool owned = true);  // return the id, must > 0

	private:
		struct AniElement;

		AniElement* FindWorkingElement(int id);
		void InsertToWorkingList(AniElement* ele);
		void FlushWorkingList();

	private:
		struct AniElement
		{
			AniElement(int id, AniObject* ani, int preId = -1, bool owned = true) : preEleId(preId), id(id), object(ani), owned(owned) {}
			~AniElement() { if(owned) delete object; }

			int preEleId;
			int id;
			bool owned;
			AniObject* object;
		};

	private:
		int lastId;

		std::set<IAniSystemListener*> listeners;

		std::vector<AniElement*> workings;
		std::vector<AniElement*> waitings;
	};

}
